package com.jeaven;

import com.jeaven.classloader.ApplicationClassLoader;
import com.jeaven.classloader.BootstrapClassLoader;
import com.jeaven.classloader.ClassLoader;
import com.jeaven.intercepter.Intercepter;
import com.jeaven.nativeBridge.java.lang.StringBridge;
import com.jeaven.rtda.heap.Heap;
import com.jeaven.rtda.heap.KClass;
import com.jeaven.rtda.heap.KMethod;

import java.io.IOException;

public class VirtualMachine {
    // TO-DO
    // 暂时没有实现
    // 要实现类加载机制
    // 要实现解释器的解释执行
    // 要实现 JIT

    public static final Heap heap;  // JVM heap --- 堆内存
    public static final Intercepter intercepter; // JVM interpreter --- JVM 执行引擎中的解释器

    static {
        heap = new Heap();
        intercepter = new Intercepter();
    }

    public void initVirtualMachine(ClassLoader classLoader) {
        registerNativeMethods();
        loadPrimitiveClasses(classLoader);
        initSystemClasses(classLoader);
    }

    // 加载 JVM 系统的启动类，比如 Class, Object, String ... 等等，不需要真的实现类，只需要注册符号即可，具体的实现都是 native 方法
    private void loadPrimitiveClasses(ClassLoader classLoader) {
        ((BootstrapClassLoader)classLoader).loadPrimitiveClass("java/lang/String");
    }

    // 注册 JVM 系统自带的类中的 native 方法
    private void registerNativeMethods() {
        StringBridge.registerNatives0();  // 注册 String 中的 native 方法
    }

    // 执行类的初始化方法来对类中的静态变量赋初值
    public void initSystemClasses(ClassLoader classLoader) {
        for(KClass kClass : heap.getClasses()) {
            KMethod initKMethod = kClass.getMethod("<init>", "()V");
//            intercepter.intercepte(initKMethod);
            // todo
            System.out.println("<init>()V [Note]:静态变量和构造函数初始化还没有实现");
        }
    }

    public void run(Args cmd) throws IOException {
        if(cmd.version) {
           return;
        }

        String currentClass = cmd.clazz;
        ClassLoader classLoader0 = new BootstrapClassLoader();  // 启动类加载器
        initVirtualMachine(classLoader0);  // 进行系统的类加载过程

        ClassLoader classLoader1 = new ApplicationClassLoader(); // 应用程序类加载器
        classLoader1.loadClass(currentClass);  // 程序的类加载过程

        //List<KClass> kClassList = heap.getClasses();
        // todo
        // 没有做静态变量初始化操作，运行父类的构造方法，接口方法的初始化等操作。

        String temp = currentClass.replace(".", "/");
        KClass kClass = heap.findClass(temp);

        if(cmd.classpath == null) { // 没有依赖的 jar 包
            KMethod mainMethod = kClass.getMainMethod();
            intercepter.intercepte(mainMethod);
            return;
        } else {  // 需要解析依赖的 jar 包
            String classpath = cmd.classpath;
            // todo
        }

    }


}
